﻿@using MQTTnet;
@using MQTTnet.Client
@using MQTTnet.Extensions.ManagedClient;
@using System.Collections.Concurrent;

<h3>MQTT订阅测试</h3>

<ValidateForm Model="@MQTTConfig">
    <Row ItemsPerRow="ItemsPerRow.Three" RowType="RowType.Inline">
        @*<BootstrapInput @bind-Value="@MQTTConfig.ID" />*@
        <BootstrapInput Readonly="true" @bind-Value="@MQTTConfig.Mqtt.Name" />
        <BootstrapInput Readonly="true" @bind-Value="@MQTTConfig.Mqtt.BrokerAddress" />
        <BootstrapInputNumber Readonly="true" @bind-Value="@MQTTConfig.Mqtt.BrokerPort" />

        <BootstrapInput Readonly="true" @bind-Value="@MQTTConfig.Name" />
        <BootstrapInput Readonly="true" @bind-Value="@MQTTConfig.Topic" />
        <Button Text="开始连接" IsAsync="true" OnClick="@(()=>OnClickOpenConnAsync())"></Button>
    </Row>
</ValidateForm>

<br />
<Console Items="@Messages" Height="200" IsAutoScroll="true" />

@implements IDisposable
@code {

    [CascadingParameter(Name = "BodyContext")]
    private object? Parameter
    {
        get { return parameter; }
        set
        {
            parameter = value;
            if (parameter is MqttTopicVO)
            {
                MQTTConfig = parameter as MqttTopicVO;
            }
        }
    }

    [Inject]
    private MessageService? MessageService { get; set; }

    private object? parameter;
    /// <summary>
    /// 传入的配置文件
    /// </summary>
    private MqttTopicVO? MQTTConfig { get; set; }

    // <summary>
    /// 按钮点击
    /// </summary>
    /// <returns></returns>
    private async Task OnClickOpenConnAsync()
    {
        MQTTConfig.Mqtt.ClientID = Guid.NewGuid().ToString("N"); //ClientID不能重复 重复会有问题
        await CoonTest(MQTTConfig.Mqtt);

    }

    /// <summary>
    /// 控制台消息
    /// </summary>
    private ConcurrentQueue<ConsoleMessageItem> Messages { get; set; } = new();



    /// <summary>
    /// 客户端
    /// </summary>
    private IManagedMqttClient managedMqttClient;

    /// <summary>
    ///是否是否已经添加
    /// </summary>
    private bool IsEnventAdd = false;

    /// <summary>
    /// 订阅主题
    /// </summary>
    /// <returns></returns>
    private async Task SubscribeTopic(string topic)
    {

        if (string.IsNullOrEmpty(topic))
        {
            await MessageService.Show(new MessageOption()
                {
                    Content = "主题不能为空!",
                    Color = Color.Danger
                });
            return;
        }

        if (managedMqttClient == null || managedMqttClient.IsConnected == false)
        {
            await MessageService.Show(new MessageOption()
                {
                    Content = "未连接请先连接!",
                    Color = Color.Danger
                });
            return;
        }

        await managedMqttClient.SubscribeAsync(topic);
        await ConsoleMessages($"订阅{topic}主题!");

    }

    private async Task CoonTest(MQTTConfigVO mQTTConfig)
    {
        try
        {
            if (managedMqttClient == null)
            {
                var mqttFactory = new MqttFactory();
                managedMqttClient = mqttFactory.CreateManagedMqttClient();
                IsEnventAdd = false;
            }
            var mqttClientOptions = new MqttClientOptionsBuilder()
                .WithTcpServer(mQTTConfig.BrokerAddress, mQTTConfig.BrokerPort)
                .WithClientId(mQTTConfig.ClientID)
                .WithCredentials(mQTTConfig.UserName, mQTTConfig.Password)
                .Build();

            var managedMqttClientOptions = new ManagedMqttClientOptionsBuilder()
                .WithClientOptions(mqttClientOptions)
                .Build();

            //注册接收消息
            if (IsEnventAdd == false)
            {
                managedMqttClient.ConnectingFailedAsync += MqttClient_ConnectingFailedAsync;
                managedMqttClient.DisconnectedAsync += MqttClient_DisconnectedAsync;
                managedMqttClient.ConnectedAsync += MqttClient_ConnectedAsync;
                managedMqttClient.ApplicationMessageReceivedAsync += MessageReceivedHandler;
                IsEnventAdd = true; //时间重复注册判断
            }

            if (managedMqttClient.IsStarted)
            {
                await managedMqttClient.StopAsync();
            }

            await managedMqttClient.StartAsync(managedMqttClientOptions);
            Messages.Enqueue(new ConsoleMessageItem { Message = $"Mqtt尝试连接!" });
        }
        catch (Exception ex)
        {
            await MessageService.Show(new MessageOption()
                {
                    Content = ex.ToString(),
                    Color = Color.Danger
                });
        }
    }


    /// <summary>
    /// 收到消息
    /// </summary>
    /// <param name="obj"></param>
    private async Task MessageReceivedHandler(MqttApplicationMessageReceivedEventArgs obj)
    {
        //Console.WriteLine("===================================================");
        //Console.WriteLine("收到消息:");
        //Console.WriteLine($"主题:{obj.ApplicationMessage.Topic}");
        //Console.WriteLine($"消息:{Encoding.UTF8.GetString(obj.ApplicationMessage.Payload)}");
        //Console.WriteLine("+++++++++++++++++++++++++++++++++++++++++++++++++++");
        //Console.WriteLine();
        string msg = $"{DateTimeOffset.Now}:{obj.ApplicationMessage.Topic}:{Encoding.UTF8.GetString(obj.ApplicationMessage.PayloadSegment)}";
        await ConsoleMessages(msg, Color.Success);
    }

    private async Task MqttClient_ConnectedAsync(MqttClientConnectedEventArgs arg)
    {
        await ConsoleMessages($"MqttMqtt客户端连接成功!" + arg.ConnectResult.ToString(), Color.Success);
        //连接成功后订阅主题
        await SubscribeTopic(MQTTConfig.Topic);
    }

    private async Task MqttClient_DisconnectedAsync(MqttClientDisconnectedEventArgs arg)
    {
        await ConsoleMessages($"Mqtt客户端连接断开!" + arg.Exception?.Message, Color.Danger);
    }

    private async Task MqttClient_ConnectingFailedAsync(ConnectingFailedEventArgs arg)
    {
        await ConsoleMessages($"Mqtt客户端连接失败!" + arg.Exception.Message, Color.Danger);
    }

    void IDisposable.Dispose()
    {
        if (managedMqttClient != null)
        {
            if (managedMqttClient.IsStarted)
            {
                managedMqttClient.StopAsync();
            }
            managedMqttClient.Dispose();
        }
    }
    /// <summary>
    /// 追加消息
    /// </summary>
    /// <param name="message"></param>
    /// <param name="color"></param>
    /// <returns></returns>
    private async Task ConsoleMessages(string message, Color color = Color.Secondary)
    {
        Messages.Enqueue(new ConsoleMessageItem { Message = message, Color = color });
        await InvokeAsync(StateHasChanged);
    }

}
